#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
分享相关数据模型
"""

from dataclasses import dataclass, field
from datetime import datetime
from typing import Dict, List, Any, Optional
import json
from enum import Enum


class CloudType(Enum):
    """云盘类型枚举"""
    TIANYI = "天翼云"
    BAIDU = "百度"
    ALIYUN = "阿里云"
    YUN115 = "115"
    QUARK = "夸克"
    LANZOU = "蓝奏云"


class ShareStatus(Enum):
    """分享状态枚举"""
    UNPROCESSED = "unprocessed"  # 未处理
    PROCESSED = "processed"      # 已处理
    ACTIVE = "active"          # 有效
    EXPIRED = "expired"        # 已过期
    DELETED = "deleted"        # 已删除
    INVALID = "invalid"        # 无效
    ACCESS_DENIED = "access_denied"  # 访问被拒绝
    PASSWORD_ERROR = "password_error"  # 密码错误


@dataclass
class CloudResource:
    """云盘资源数据模型"""
    clouds_type: str
    share_code: str
    access_code: str = ""
    share_name: str = ""
    full_url: str = ""
    share_status: str = ShareStatus.UNPROCESSED.value
    share_time: Optional[datetime] = None
    file_info_json: str = ""
    id: Optional[int] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    
    def __post_init__(self):
        """初始化后处理"""
        if self.created_at is None:
            self.created_at = datetime.now()
        if self.updated_at is None:
            self.updated_at = datetime.now()
    
    @property
    def file_info(self) -> Dict[str, Any]:
        """获取文件信息字典"""
        if self.file_info_json:
            try:
                return json.loads(self.file_info_json)
            except json.JSONDecodeError:
                return {}
        return {}
    
    @file_info.setter
    def file_info(self, value: Dict[str, Any]):
        """设置文件信息"""
        if isinstance(value, dict):
            self.file_info_json = json.dumps(value, ensure_ascii=False, indent=2)
        else:
            self.file_info_json = str(value)
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'id': self.id,
            'clouds_type': self.clouds_type,
            'share_code': self.share_code,
            'access_code': self.access_code,
            'share_name': self.share_name,
            'full_url': self.full_url,
            'share_status': self.share_status,
            'share_time': self.share_time.isoformat() if self.share_time else None,
            'file_info_json': self.file_info_json,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'updated_at': self.updated_at.isoformat() if self.updated_at else None
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'CloudResource':
        """从字典创建实例"""
        # 处理时间字段
        share_time = None
        if data.get('share_time'):
            if isinstance(data['share_time'], str):
                try:
                    share_time = datetime.fromisoformat(data['share_time'])
                except ValueError:
                    share_time = None
            elif isinstance(data['share_time'], datetime):
                share_time = data['share_time']
        
        created_at = None
        if data.get('created_at'):
            if isinstance(data['created_at'], str):
                try:
                    created_at = datetime.fromisoformat(data['created_at'])
                except ValueError:
                    created_at = None
            elif isinstance(data['created_at'], datetime):
                created_at = data['created_at']
        
        updated_at = None
        if data.get('updated_at'):
            if isinstance(data['updated_at'], str):
                try:
                    updated_at = datetime.fromisoformat(data['updated_at'])
                except ValueError:
                    updated_at = None
            elif isinstance(data['updated_at'], datetime):
                updated_at = data['updated_at']
        
        return cls(
            id=data.get('id'),
            clouds_type=data['clouds_type'],
            share_code=data['share_code'],
            access_code=data.get('access_code', ''),
            share_name=data.get('share_name', ''),
            full_url=data.get('full_url', ''),
            share_status=data.get('share_status', ShareStatus.UNPROCESSED.value),
            share_time=share_time,
            file_info_json=data.get('file_info_json', ''),
            created_at=created_at,
            updated_at=updated_at
        )
    
    def is_processed(self) -> bool:
        """检查是否已处理"""
        return self.share_status != ShareStatus.UNPROCESSED.value
    
    def get_file_count(self) -> int:
        """获取文件数量"""
        file_info = self.file_info
        if 'files' in file_info:
            return len([f for f in file_info['files'] if f.get('type') == 'file'])
        return 0
    
    def get_folder_count(self) -> int:
        """获取文件夹数量"""
        file_info = self.file_info
        if 'files' in file_info:
            return len([f for f in file_info['files'] if f.get('type') == 'folder'])
        return 0
    
    def get_total_size(self) -> int:
        """获取总大小（字节）"""
        file_info = self.file_info
        total_size = 0
        if 'files' in file_info:
            for file_item in file_info['files']:
                if file_item.get('type') == 'file' and 'size' in file_item:
                    total_size += file_item['size']
        return total_size
    
    def get_file_types(self) -> Dict[str, int]:
        """获取文件类型统计"""
        file_info = self.file_info
        file_types = {}
        if 'files' in file_info:
            for file_item in file_info['files']:
                if file_item.get('type') == 'file':
                    ext = file_item.get('name', '').split('.')[-1].lower() if '.' in file_item.get('name', '') else 'unknown'
                    file_types[ext] = file_types.get(ext, 0) + 1
        return file_types
    
    def format_size(self, size_bytes: int = None) -> str:
        """格式化文件大小"""
        if size_bytes is None:
            size_bytes = self.get_total_size()
        
        if size_bytes == 0:
            return "0 B"
        
        units = ['B', 'KB', 'MB', 'GB', 'TB']
        unit_index = 0
        size = float(size_bytes)
        
        while size >= 1024 and unit_index < len(units) - 1:
            size /= 1024
            unit_index += 1
        
        return f"{size:.2f} {units[unit_index]}"
    
    def get_summary(self) -> str:
        """获取资源摘要"""
        file_count = self.get_file_count()
        folder_count = self.get_folder_count()
        total_size = self.format_size()
        
        summary_parts = []
        if file_count > 0:
            summary_parts.append(f"{file_count}个文件")
        if folder_count > 0:
            summary_parts.append(f"{folder_count}个文件夹")
        if total_size != "0 B":
            summary_parts.append(f"总大小: {total_size}")
        
        return ", ".join(summary_parts) if summary_parts else "空分享"
    
    def validate(self) -> List[str]:
        """验证数据完整性"""
        errors = []
        
        if not self.clouds_type:
            errors.append("云盘类型不能为空")
        if not self.share_code:
            errors.append("分享码不能为空")
        
        # 验证云盘类型是否有效
        valid_types = [ct.value for ct in CloudType]
        if self.clouds_type not in valid_types:
            errors.append(f"无效的云盘类型: {self.clouds_type}")
        
        # 验证分享状态是否有效
        valid_statuses = [ss.value for ss in ShareStatus]
        if self.share_status not in valid_statuses:
            errors.append(f"无效的分享状态: {self.share_status}")
        
        return errors
    
    def __str__(self) -> str:
        return f"CloudResource({self.clouds_type}, {self.share_code}, {self.share_status})"
    
    def __repr__(self) -> str:
        return self.__str__()


@dataclass
class ImportResult:
    """导入结果数据模型"""
    success_count: int = 0
    skip_count: int = 0
    error_count: int = 0
    errors: List[str] = field(default_factory=list)
    imported_resources: List[CloudResource] = field(default_factory=list)
    skipped_resources: List[CloudResource] = field(default_factory=list)
    
    def add_success(self, resource: CloudResource):
        """添加成功导入的资源"""
        self.success_count += 1
        self.imported_resources.append(resource)
    
    def add_skip(self, resource: CloudResource):
        """添加跳过的资源"""
        self.skip_count += 1
        self.skipped_resources.append(resource)
    
    def add_error(self, error_msg: str):
        """添加错误信息"""
        self.error_count += 1
        self.errors.append(error_msg)
    
    @property
    def total_count(self) -> int:
        """总处理数量"""
        return self.success_count + self.skip_count + self.error_count
    
    def get_summary(self) -> str:
        """获取导入摘要"""
        return f"导入完成: 成功{self.success_count}, 跳过{self.skip_count}, 错误{self.error_count}"
    
    def __str__(self) -> str:
        return self.get_summary()


@dataclass
class CrawlResult:
    """爬取结果数据模型"""
    success_count: int = 0
    error_count: int = 0
    errors: List[str] = field(default_factory=list)
    processed_resources: List[CloudResource] = field(default_factory=list)
    
    def add_success(self, resource: CloudResource):
        """添加成功处理的资源"""
        self.success_count += 1
        self.processed_resources.append(resource)
    
    def add_error(self, error_msg: str):
        """添加错误信息"""
        self.error_count += 1
        self.errors.append(error_msg)
    
    @property
    def total_count(self) -> int:
        """总处理数量"""
        return self.success_count + self.error_count
    
    def get_summary(self) -> str:
        """获取爬取摘要"""
        return f"爬取完成: 成功{self.success_count}, 错误{self.error_count}"
    
    def __str__(self) -> str:
        return self.get_summary()